#ifndef MACROS_H
#define	MACROS_H

// Useful sed commands:
// sed -i 's/\(grab_lock_rw.*\)FILE_AND_LINE2/\1FL_GRABRW/g' $(ack -l "grab_lock_rw.*FILE_AND_LINE2")
// sed -i 's/\(grab_lock_r.*\)FILE_AND_LINE2/\1FL_GRABRR/g' $(ack -l "grab_lock_r.*FILE_AND_LINE2")
// sed -i 's/\(RELEASE_LOCK(.*\))/\1);
// sed -i 's/grab_lock_r(\(.*\),.*/LOCK4READ(\1);/g' $(ack -l "grab_lock_r\(") 
// sed -i 's/grab_lock_rw(\(.*\),.*/LOCK4WRITE(\1);/g' $(ack -l "grab_lock_rw\(") 
// sed -i 's/release_lock(\(.*\),.*/RELEASE_LOCK(\1);/g' $(ack -l "release_lock\(") 
#define INT_STRINGIFY(x)	#x
#define INT_TOSTRING(x)		INT_STRINGIFY(x)
#define FILE_AND_LINE		__FILE__ ":" INT_TOSTRING(__LINE__)	"\0"
#define FILE_AND_LINE_N		__FILE__ ":" INT_TOSTRING(__LINE__)	"\n\0"

// Use the macros below instead of calling the functions directly.
// Using these macros allows us to quickly change the arguments later.
#ifdef VERBOSE_LOCKING
	#define LOCK4READ(x)	{grab_lock_r((x),  "GRAB-R:  "  INT_TOSTRING(x)  "\t"  FILE_AND_LINE_N);};
	#define LOCK4WRITE(x)	{grab_lock_rw((x), "GRAB-RW: "  INT_TOSTRING(x)  "\t"  FILE_AND_LINE_N);};
	#define RELEASE_LOCK(x)	{release_lock((x), "RELEASE: "  INT_TOSTRING(x)  "\t"  FILE_AND_LINE_N);};
#else
	#define LOCK4READ(x)	{grab_lock_r2((x));};
	#define LOCK4WRITE(x)	{grab_lock_rw2((x));};
	#define RELEASE_LOCK(x)	{release_lock2((x));};
#endif

#define TRACE(x)	{kprints("TRACE: " FILE_AND_LINE ":\t " #x "\n\0");}
#define DEBUG(x)	{kprints("DEBUG: " FILE_AND_LINE ":\t (" #x ") = 0x\0"); kprinthex((long)(x)); kprints("\n\0");}
#define FAIL(x)		{kprints("FAIL:  " FILE_AND_LINE ":\t (" #x ") = 0x\0"); kprinthex((long)(x));}

#define ENSURE(x,code)			{ if (!(x)) {FAIL(x); kprints("\n\0"); code} }
#define MENSURE(x,msg,code)		{ if (!(x)) {FAIL(x); kprints(" Reason: " msg "\0");  kprints("\n\0"); code} }


#endif	/* MACROS_H */

